﻿using System;
using System.Text;
using System.Collections;
using System.IO;
using System.Xml;
using System.Globalization;
using System.Collections.Generic;
using System.Drawing;
using RAP.Framework.Libary.Utils.Reflector;
using System.Reflection;
using System.Text.RegularExpressions;
using RAP.Framework.Libary.JSON.Conversion;
using RAP.Framework.Libary.JSON;
using System.Data;
using System.Collections.Specialized;
using RAP.Framework.Libary.Utils.Interfaces;

namespace RAP.Framework.Libary.Utils
{
  /// <summary>
  /// 基础对象扩展
  /// </summary>
  public static partial class Extensions
  {
    #region 基础对象扩展
    /// <summary>
    /// 检测当前对象是否为字符串类型
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static bool IsString(this object obj)
    {
      return obj != null ? obj.GetType() == typeof(string) : false;
    }

    /// <summary>
    /// 检测当前对象是否是集合
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static bool IsList(this object obj)
    {
      if (obj == null) return false;
      if (obj is IDictionary) return false;
      return obj is ICollection;
    }

    /// <summary>
    /// 是否是值类型
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static bool IsValueType(this object obj)
    {
      TypeCode typeCode = Type.GetTypeCode(obj.GetType());
      return typeCode != TypeCode.Object && typeCode != TypeCode.Empty;
    }

    /// <summary>
    /// 检测当前对象是否为日期类型
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static bool IsDateTime(this object obj)
    {
      return obj != null ? obj.GetType() == typeof(DateTime) : false;
    }

    /// <summary>
    /// 判断当前对象是否为null或空字符串或空集合
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static bool IsNullOrEmpty(this object obj)
    {
      if (obj == null || obj == DBNull.Value)
      {
        return true;
      }
      if (obj is string)
      {
        return obj.ToString().IsNullOrEmpty();
      }
      if (obj is ICollection)
      {
        ICollection col = obj as ICollection;
        if (col.Count == 0)
        {
          return true;
        }
        foreach (object item in col)
        {
          if (!item.IsNullOrEmpty())
          {
            return false;
          }
        }
        return true;
      }
      return false;
    }

    /// <summary>
    /// 获取不为空的第一个参数
    /// </summary>
    /// <param name="arguments"></param>
    /// <returns></returns>
    public static object IsNullValue(this object value, params object[] arguments)
    {
      if (value != null && value != DBNull.Value)
      {
        return value;
      }
      if (arguments.Length == 0)
      {
        return value;
      };
      for (int i = 0; i < arguments.Length; i++)
      {
        var val = arguments[i];
        if (val != null && val != DBNull.Value)
        {
          return val;
        }
      };
      return null;
    }

    /// <summary>
    /// 判断当前对象是否为空，如果为空这按顺序取出values中第一个不为空的值
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="getDefaultValue"></param>
    /// <returns></returns>
    public static object IsNullValue(this object obj, Func<object> getDefaultValue)
    {
      if (obj != null && obj != DBNull.Value)
      {
        return obj;
      }
      if (getDefaultValue == null)
      {
        return null;
      }
      return getDefaultValue();
    }

    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <param name="values"></param>
    /// <returns></returns>
    public static T IsNullValue<T>(this object obj, params object[] values)
    {
      if (obj != null && obj != DBNull.Value)
      {
        if (obj is IConvertible)
        {
          return (T)Convert.ChangeType(obj, typeof(T));
        }
        return (T)obj;
      }
      if (values == null)
      {
        return default(T);
      }
      foreach (object val in values)
      {
        if (val != null && val != DBNull.Value)
        {
          if (val is Func<T>)
          {
            var value = (val as Func<T>)();
            if (value != null && (object)value != DBNull.Value)
            {
              return value;
            }
          }
          else
          {
            if (val is IConvertible)
            {
              return (T)Convert.ChangeType(val, typeof(T));
            }
            return (T)val;
          }
        }
      }
      return default(T);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <param name="getDefaultValue"></param>
    /// <returns></returns>
    public static T IsNullValue<T>(this T obj, Func<T> getDefaultValue)
    {
      if (obj != null)
      {
        return obj;
      }
      if (getDefaultValue == null)
      {
        return default(T);
      }
      return getDefaultValue();
    }

    /// <summary>
    /// 判断当前字符串是否为空或""，如果为空或""这按顺序取出values中第一个不为空的值
    /// </summary>
    /// <param name="str"></param>
    /// <param name="values"></param>
    /// <returns></returns>
    public static string IsEmptyValue(this object str, params string[] values)
    {
      if (str.IsNotNullOrEmpty())
      {
        return str.ToString();
      }
      if (values == null)
      {
        return null;
      }
      foreach (string val in values)
      {
        if (val.IsNotNullOrEmpty())
        {
          return val;
        }
      }
      return null;
    }

    /// <summary>
    /// 如果当前字符串不为null或empty则返回，否则返回第一个不为null或empty的值
    /// </summary>
    /// <param name="str"></param>
    /// <param name="values"></param>
    /// <returns></returns>
    public static string IsNullOrEmptyValue(this object str, params string[] values)
    {
      if (str.IsNotNullOrEmpty())
      {
        return str.ToString();
      }
      foreach (string val in values)
      {
        if (val.IsNotNullOrEmpty())
        {
          return val;
        }
      }
      return null;
    }

    /// <summary>
    /// 判断一个对象是否为null或则为empty（字符串会集合均可判断），如果不是，则直接返回对象，否则返回第一个不为null或Empty的值
    /// </summary>
    /// <param name="str"></param>
    /// <param name="getValues"></param>
    /// <returns></returns>
    public static string IsNullOrEmptyValue(this object str, params Func<string>[] getValues)
    {
      if (str.IsNotNullOrEmpty())
      {
        return str.ToString();
      }
      foreach (Func<string> fun in getValues)
      {
        if (fun != null)
        {
          var val = fun();
          if (val.IsNotNullOrEmpty())
          {
            return val;
          }
        }
      }
      return null;
    }

    /// <summary>
    /// 判断当前对象不是为null或空字符串或空集合
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static bool IsNotNullOrEmpty(this object obj)
    {
      return !obj.IsNullOrEmpty();
    }

    /// <summary>
    /// 判断当前字符串是否为null或空字符串
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static bool IsNullOrEmpty(this string obj)
    {
      return obj == null || string.IsNullOrEmpty(obj.ToString().Trim());
    }

    /// <summary>
    /// 判断当前集合是否为null或Count为0
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static bool IsNullOrEmpty(this ICollection obj)
    {
      return obj == null || obj.Count == 0;
    }

    /// <summary>
    /// 判断当前字符串不是为null或空字符串
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static bool IsNotNullOrEmpty(this string obj)
    {
      return obj != null && !string.IsNullOrEmpty(obj.ToString().Trim());
    }

    /// <summary>
    /// 检测当前路径的文件是否存在
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    public static bool IsFileExists(this string file)
    {
      if (file.IsNullOrEmpty())
      {
        return false;
      }
      return File.Exists(file);
    }

    /// <summary>
    /// 检测当前路径的文件夹是否存在
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public static bool IsPathExists(this string path)
    {
      if (path.IsNullOrEmpty())
      {
        return false;
      }
      return Directory.Exists(path);
    }

    /// <summary>
    /// 判断当前集合不是为null或Count为0
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static bool IsNotNullOrEmpty(this ICollection obj)
    {
      return obj != null && obj.Count > 0;
    }

    /// <summary>
    /// 检测当前对象是否为整数
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static bool IsInt32(this object obj)
    {
      if (obj == null || obj == DBNull.Value)
      {
        return false;
      }
      int t;
      if (int.TryParse(obj.ToString(), out t))
      {
        return t.ToString().Equals(obj);
      }
      else
      {
        return false;
      }
    }

    /// <summary>
    /// 检测当前对象是否为数字
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static bool IsNumber(this object obj, bool tryParse = true)
    {
      if (obj.IsNullOrEmpty() || obj == DBNull.Value)
      {
        return false;
      }
      TypeCode typeCode = Type.GetTypeCode(obj.GetType());
      switch (typeCode)
      {
        case TypeCode.Int16:
        case TypeCode.Int32:
        case TypeCode.Int64:
        case TypeCode.SByte:
        case TypeCode.Single:
        case TypeCode.UInt16:
        case TypeCode.UInt32:
        case TypeCode.UInt64:
        case TypeCode.Decimal:
        case TypeCode.Double:
          return true;
      }
      if (tryParse)
      {
        double value = double.MinValue;
        if (double.TryParse(obj.ToString(), out value))
        {
          return true;
        }
      }
      return false;
    }

    /// <summary>
    /// 将当前对象序列化为JSON字符串
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static string ToJSON(this object obj)
    {
      if (obj == null)
      {
        return null;
      }
      return JsonConvert.ExportToString(obj);
    }

    /// <summary>
    /// 将当前对象转换成整数
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultValue">对象为null或不是数字时返回的默认值，默认为0</param>
    /// <returns></returns>
    public static Int32 ToInt32Value(this object obj, Int32 defaultValue = 0)
    {
      if (obj == null || obj == DBNull.Value)
      {
        return defaultValue;
      }
      if (obj is Int32)
      {
        return (Int32)obj;
      }
      if (obj is JsonNumber)
      {
        return ((JsonNumber)obj).ToInt32();
      }
      Func<int> convert = () =>
      {
        int value = defaultValue;
        if (int.TryParse(obj.ToString(), NumberStyles.Any, NumberFormatInfo.CurrentInfo, out value))
        {
          return value;
        }
        else
        {
          double dValue = 0.0d;
          dValue = obj.ToDoubleValue(Convert.ToDouble(defaultValue));
          return Convert.ToInt32(dValue);
        }
      };
      if (obj is string)
      {
        return convert();
      }
      try
      {
        return Convert.ToInt32(obj);
      }
      catch
      {
        return convert();
      }
    }


    /// <summary>
    /// 将当前对象转换成长整型
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultValue">对象为null或不是数字时返回的默认值，默认为0</param>
    /// <returns></returns>
    public static Int64 ToInt64Value(this object obj, long defaultValue = 0)
    {
      if (obj == null || obj == DBNull.Value)
      {
        return defaultValue;
      }
      if (obj is Int64)
      {
        return (Int64)obj;
      }
      if (obj is JsonNumber)
      {
        return ((JsonNumber)obj).ToInt64();
      }
      Func<long> convert = () =>
      {
        long value = defaultValue;
        if (long.TryParse(obj.ToString(), NumberStyles.Any, NumberFormatInfo.CurrentInfo, out value))
        {
          return value;
        }
        else
        {
          double dValue = 0.0d;
          dValue = obj.ToDoubleValue(System.Convert.ToDouble(defaultValue));
          return Convert.ToInt64(dValue);
        }
      };
      if (obj is string)
      {
        return convert();
      }
      try
      {
        return System.Convert.ToInt64(obj);
      }
      catch
      {
        return convert();
      }
    }

    /// <summary>
    /// 将指定对象转换成整形数组
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultItemValue">数据项的默认值</param>
    /// <returns></returns>
    public static IList<int> ToInt32List(this object obj, int defaultItemValue = 0)
    {
      return obj.ConvertItemType((value) =>
     {
       return value.ToInt32Value(defaultItemValue);
     });
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultItemValue"></param>
    /// <returns></returns>
    public static IList<string> ToStringList(this object obj, string defaultItemValue = "")
    {
      return obj.ConvertItemType((value) =>
      {
        return value.ToStringValue(defaultItemValue);
      });

    }

    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <param name="parseFunc"></param>
    /// <returns></returns>
    public static IList<T> ConvertItemType<T>(this object obj, Func<object, T> parseFunc)
    {
      IList<T> result = new List<T>();
      Func<object, bool> func = (value) =>
      {
        result.Add(parseFunc(value));
        return true;
      };
      if (obj is IEnumerable)
      {
        ((IEnumerable)obj).Map(func);
      }
      else if (obj is String)
      {
        obj.ToString().Split(',').Map(func);
      }
      return result;

    }

    /// <summary>
    /// 将当前对象转换成浮点数
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultValue">对象为null或不是数字时返回的默认值，默认为0</param>
    /// <returns></returns>
    public static float ToFloatValue(this object obj, float defaultValue = 0f)
    {
      if (obj == null || obj == DBNull.Value)
      {
        return defaultValue;
      }
      if (obj is float)
      {
        return (float)obj;
      }
      if (obj is JsonNumber)
      {
        return ((JsonNumber)obj).ToSingle();
      }
      try
      {
        return Convert.ToSingle(obj);
      }
      catch
      {
        float value = defaultValue;
        if (float.TryParse(obj.ToString(), NumberStyles.Any, NumberFormatInfo.CurrentInfo, out value))
        {
          return value;
        }
        return defaultValue;
      }
    }

    /// <summary>
    /// 将当前对象转换成双精度数
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultValue">对象为null或不是数字时返回的默认值，默认为0</param>
    /// <returns></returns>
    public static decimal ToDecimalValue(this object obj, decimal defaultValue = 0m)
    {
      if (obj == null || obj == DBNull.Value)
      {
        return defaultValue;
      }
      if (obj is decimal)
      {
        return (decimal)obj;
      }
      if (obj is JsonNumber)
      {
        return ((JsonNumber)obj).ToDecimal();
      }
      try
      {
        return Convert.ToDecimal(obj);
      }
      catch
      {
        decimal value = defaultValue;
        if (decimal.TryParse(obj.ToString(), NumberStyles.Any, NumberFormatInfo.CurrentInfo, out value))
        {
          return value;
        }
        return defaultValue;
      }
    }

    /// <summary>
    /// 将当前对象转换成双精度数
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultValue">对象为null或不是数字时返回的默认值，默认为0</param>
    /// <returns></returns>
    public static double ToDoubleValue(this object obj, double defaultValue = 0d)
    {
      if (obj == null || obj == DBNull.Value)
      {
        return defaultValue;
      }
      if (obj is double)
      {
        return (double)obj;
      }
      if (obj is JsonNumber)
      {
        return ((JsonNumber)obj).ToDouble();
      }
      try
      {
        return Convert.ToDouble(obj);
      }
      catch
      {
        double value = defaultValue;
        if (double.TryParse(obj.ToString(), NumberStyles.Any, NumberFormatInfo.CurrentInfo, out value))
        {
          return value;
        }
        return defaultValue;
      }
    }


    /// <summary>
    /// 将当前对象转换成短整型
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultValue">对象为null或不是数字时返回的默认值，默认为0</param>
    /// <returns></returns>
    public static short ToShortValue(this object obj, short defaultValue = 0)
    {
      if (obj == null || obj == DBNull.Value)
      {
        return defaultValue;
      }
      try
      {
        return System.Convert.ToInt16(obj);
      }
      catch
      {
        short value = defaultValue;
        if (short.TryParse(obj.ToString(), NumberStyles.Any, NumberFormatInfo.CurrentInfo, out value))
        {
          return value;
        }
        return defaultValue;
      }
    }

    /// <summary>
    /// 将当前对象转换成Boolean对象
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultValue"></param>
    /// <returns></returns>
    public static bool ToBooleanValue(this object obj, bool defaultValue = false)
    {
      if (obj.IsNullOrEmpty())
      {
        return defaultValue;
      }
      if (obj is bool)
      {
        return (bool)obj;
      }
      if (obj is JsonNumber)
      {
        return obj.ToInt32Value() != 0;
      }
      TypeCode typeCode = Type.GetTypeCode(obj.GetType());
      switch (typeCode)
      {
        case TypeCode.Byte:
        case TypeCode.Decimal:
        case TypeCode.Double:
        case TypeCode.Int16:
        case TypeCode.Int32:
        case TypeCode.Int64:
        case TypeCode.SByte:
        case TypeCode.Single:
        case TypeCode.UInt16:
        case TypeCode.UInt32:
        case TypeCode.UInt64:
          return ((int)Convert.ChangeType(obj, typeof(int))) != 0;

        case TypeCode.String:
          string value = obj.ToString().ToLower();
          return value != "false" && value != "0";

        case TypeCode.Object:
          return obj != null;
      }

      try
      {
        return bool.Parse(obj.ToString());
      }
      catch
      {
      }
      return defaultValue;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultValue"></param>
    /// <returns></returns>
    public static DateTime? ToDateTimeValue(this object obj, DateTime? defaultValue = null)
    {
      if (obj == null)
      {
        return defaultValue;
      }
      try
      {
        return DateTime.Parse(obj.ToString());
      }
      catch { }
      return defaultValue;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultValue"></param>
    /// <returns></returns>
    public static string ToStringValue(this object obj, string defaultValue)
    {
      return obj.IsNullOrEmptyValue(defaultValue);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultValue"></param>
    /// <returns></returns>
    public static IList ToListValue(this object obj, IList defaultValue = null)
    {
      if (obj == null)
      {
        return defaultValue;
      }
      return (IList)obj;
    }

    /// <summary>
    /// 获取指定对象指定表达式的字符串值
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="expression">表达式</param>
    /// <param name="defaultValue">对象为null或表达式返回为null时的默认值，默认为null</param>
    /// <returns></returns>
    public static string GetString(this object obj, string expression, String defaultValue = null)
    {
      return obj.GetValue(expression).ToStringValue(defaultValue);
    }

    /// <summary>
    /// 获取指定对象指定表达式的整数值
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="expression">表达式</param>
    /// <param name="defaultValue">对象为null或表达式返回为null时的默认值，默认为0</param>
    /// <returns></returns>
    public static Int32 GetInt32(this object obj, string expression, Int32 defaultValue = 0)
    {
      return obj.GetValue(expression).ToInt32Value(defaultValue);
    }

    /// <summary>
    /// 获取指定对象指定表达式的Bool值
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="expression">表达式</param>
    /// <param name="defaultValue">对象为null或表达式返回为null时的默认值，默认为false</param>
    /// <returns></returns>
    public static bool GetBoolean(this object obj, string expression, bool defaultValue = false)
    {
      return obj.GetValue(expression).ToBooleanValue(defaultValue);
    }

    /// <summary>
    /// 获取指定对象指定表达式的日期值
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="expression">表达式</param>
    /// <param name="defaultValue">对象为null或表达式返回为null时的默认值，默认为null</param>
    /// <returns></returns>
    public static DateTime? GetDateTime(this object obj, string expression, DateTime? defaultValue = null)
    {
      return obj.GetValue(expression).ToDateTimeValue(defaultValue);
    }

    /// <summary>
    /// 获取指定对象指定表达式的值
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="expression">表达式</param>
    /// <param name="defaultValue">对象为null或表达式返回为null时的默认值，默认为null</param>
    /// <returns></returns>
    public static object GetValue(this object obj, string expression, object defaultValue = null)
    {
      return PropertyReflectorUtils.GetValue(obj, expression).IsNullValue(defaultValue);
    }

    /// <summary>
    /// 获取指定对象的多个属性值并返回成键值对象(IDictionary)
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="fields"></param>
    /// <returns></returns>
    public static IDictionary GetValues(this object obj, params string[] fields)
    {
      if (obj.IsNullOrEmpty())
      {
        return null;
      }
      var result = new ListDictionary();
      if (fields.IsNotNullOrEmpty())
      {
        if (obj is IDictionary)
        {
          //如果是键值对，则直接复制键值对
          (obj as IDictionary).CopyTo(result, fields);
        }
        else
        {
          foreach (string field in fields)
          {
            result[field] = obj.GetValue(field);
          }
        }
      }
      else
      {
        //获取所有公共[Public]属性
        if (obj is IDictionary)
        {
          //如果是键值对，则直接复制键值对
          (obj as IDictionary).CopyTo(result);
        }
        else
        {
          foreach (var property in obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
          {
            result[property.Name] = property.GetValue(obj);
          }
        }
      }

      return result;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="expression"></param>
    /// <param name="getDefaultValue"></param>
    /// <returns></returns>
    public static object GetValue(this object obj, string expression, Func<object> getDefaultValue)
    {
      object value = obj.GetValue(expression);
      return value.IsNullValue(getDefaultValue);
    }

    /// <summary>
    /// 设置指定对象指定表达式的值
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="expression"></param>
    /// <param name="value"></param>
    public static void SetValue(this object obj, string expression, object value)
    {
      if (obj is IDictionary)
      {
        if (expression.IsNotNullOrEmpty())
        {
          (obj as IDictionary).SetDictionaryValue(expression, value);
        }
        else if (value is IDictionary)
        {
          (value as IDictionary).CopyTo(obj as IDictionary);
        }
      }
      else if (obj is IKeyValuePair)
      {
        if (expression.IsNotNullOrEmpty())
        {
          (obj as IKeyValuePair)[expression] = value;
        }
        else if (value is IDictionary)
        {
          (value as IDictionary).CopyTo(obj as IKeyValuePair);
        }
      }
      else
      {
        PropertyReflectorUtils.SetValue(obj, expression, value);
      }
    }

    /// <summary>
    /// 获取指定对象指定表达式的泛型值
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="expression">表达式</param>
    /// <param name="defaultValue">对象为null或表达式返回为null时的默认值，默认为null</param>
    /// <returns></returns>
    public static T GetValue<T>(this object obj, string expression, object defaultValue = null)
    {
      return PropertyReflectorUtils.GetValue(obj, expression).IsNullValue<T>(defaultValue);
    }

    #region Convert Utils


    /// <summary>
    /// 
    /// </summary>
    /// <param name="type"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public static object ConvertValue(this object value, Type type)
    {
      return value.ConvertValue(Type.GetTypeCode(type));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="typeCode"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public static object ConvertValue(this object value, TypeCode typeCode)
    {
      switch (typeCode)
      {
        case TypeCode.Decimal:
          return value.ToDecimalValue();
        case TypeCode.Double:
          return value.ToDoubleValue();
        case TypeCode.Int16:
        case TypeCode.Int32:
        case TypeCode.UInt16:
        case TypeCode.UInt32:
        case TypeCode.SByte:
        case TypeCode.Byte:
          return value.ToInt32Value();

        case TypeCode.Int64:
        case TypeCode.UInt64:
          return value.ToInt64Value();

        case TypeCode.Single:
          return value.ToFloatValue();

        case TypeCode.String:
          return value.ToString();

        case TypeCode.Boolean:
          return value.ToBooleanValue();

        case TypeCode.DateTime:
          return value.ToString().ToDateTimeValue();
        case TypeCode.Object:
          if (value.IsString())
          {
            return value.ToString().Eval();
          }
          return value;
        default:
          return value;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="value"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    public static object ConvertValue(this object value, ConvertableTypes type)
    {
      switch (type)
      {
        case ConvertableTypes.DateTime:
        case ConvertableTypes.Date:
          return value.ConvertValue(TypeCode.DateTime);

        case ConvertableTypes.Int32:
        case ConvertableTypes.Int:
          return value.ConvertValue(TypeCode.Int32);

        case ConvertableTypes.Number:
        case ConvertableTypes.Double:
          return value.ConvertValue(TypeCode.Double);

        case ConvertableTypes.Int32List:
          return value.ToInt32List();

        case ConvertableTypes.StringList:
          return value.ToStringList();

        case ConvertableTypes.String:
        default:
          return value.ToString();
      }
    }

    #endregion Convert Utils

    #region compare
    /// <summary>
    /// 判断俩对象是否相同
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static bool IsEquals(this object a, object b)
    {
      if (a == null)
      {
        return b == null;
      }
      if (b == null)
      {
        return false;
      }
      if (a.IsValueType() && b.IsValueType())
      {
        return a.Equals(b);
      }
      if (a is IDictionary)
      {
        return a == b || ((IDictionary)a).IsEquals((IDictionary)b);
      }
      else if (a is IList)
      {
        return a == b || ((IList)a).IsEquals((IList)b);
      }
      return a.Equals(b);
    }

    /// <summary>
    /// 比较两个对象的大小，相同返回0，value1大于value2返回1，否则返回-1 
    /// </summary>
    /// <param name="value1"></param>
    /// <param name="value2"></param>
    /// <returns></returns>
    public static int Compare(this object value1, object value2)
    {
      if (value1 == value2)
      {
        return 0;
      }
      if (value1 == null)
      {
        if (value2 != null)
        {
          return -1;
        }
      }
      if (value2 == null)
      {
        if (value1 != null)
        {
          return 1;
        }
      }

      Type type1 = value1.GetType();
      Type type2 = value2.GetType();
      if (!(value1 is IComparable && value2 is IComparable))
      {
        if (value1 is IConvertible)
        {
          value1 = value1.ConvertValue(type2);
        }
        else if (value2 is IConvertible)
        {
          value2 = value2.ConvertValue(type1);
        }
        else
        {
          value1 = value1.ToString();
          value2 = value2.ToString();
          type1 = type2 = typeof(string);
        }
        type1 = type2;
      }
      if (type1 != type2)
      {
        value2 = value2.ConvertValue(type1);
      }
      if (value1 is IComparable)
      {
        return ((IComparable)value1).CompareTo(value2);
      }
      return ((IComparable)value2).CompareTo(value1);
    }

    /// <summary>
    /// 判断指定两个值（数值大小）是否相等
    /// </summary>
    /// <param name="value1"></param>
    /// <param name="value2"></param>
    /// <returns></returns>
    public static bool IsEqual(this object value1, object value2)
    {
      return value1.Compare(value2) == 0;
    }

    /// <summary>
    /// 判断指定两个对象是否不相等
    /// </summary>
    /// <param name="value1"></param>
    /// <param name="value2"></param>
    /// <returns></returns>
    public static bool IsNotEqual(this object value1, object value2)
    {
      return !IsEqual(value1, value2);
    }


    /// <summary>
    /// 判断指定值是否小于指定值
    /// </summary>
    /// <param name="value1"></param>
    /// <param name="value2"></param>
    /// <returns></returns>
    public static bool IsLessThan(this object value1, object value2)
    {
      return value1.Compare(value2) < 0;
    }

    /// <summary>
    /// 判断指定值是否小于等于指定值
    /// </summary>
    /// <param name="value1"></param>
    /// <param name="value2"></param>
    /// <returns></returns>
    public static bool IsLessEqual(this object value1, object value2)
    {
      return value1.Compare(value2) <= 0;
    }

    /// <summary>
    /// 判断指定值是否大于指定值
    /// </summary>
    /// <param name="value1"></param>
    /// <param name="value2"></param>
    /// <returns></returns>
    public static bool IsGreaterThan(this object value1, object value2)
    {
      return value1.Compare(value2) > 0;
    }

    /// <summary>
    /// 判断指定值是否大于等于指定值
    /// </summary>
    /// <param name="value1"></param>
    /// <param name="value2"></param>
    /// <returns></returns>
    public static bool IsGreaterEqual(this object value1, object value2)
    {
      return value1.Compare(value2) >= 0;
    }
    #endregion

    /// <summary>
    /// 将当前对象转换成指定类型的枚举对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <param name="defaultValue"></param>
    /// <returns></returns>
    public static T ToEnumValue<T>(this object obj, T defaultValue = default(T))
    {
      object value = obj;
      if (value == null || value.ToString() == string.Empty)
      {
        return defaultValue;
      }
      return (T)System.Enum.Parse(typeof(T), value.ToString());
    }

    /// <summary>
    /// 判断对象是否是AnonymousType
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static bool IsAnonymousType(this object obj)
    {
      if (obj == null)
      {
        return false;
      }
      return obj.GetType().Name.StartsWith("<>f__AnonymousType");
    }

    /// <summary>
    /// 将指定对象转换成 IDictionary 类型
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static IDictionary ToDictionary(this object obj)
    {
      if (obj is IDictionary)
      {
        return obj as IDictionary;
      }
      if (obj.IsString())
      {
        return obj.ToString().ToDictionary();
      }
      if (obj.IsAnonymousType())
      {
        return Newtonsoft.Json.JsonConvert.SerializeObject(obj).ToDictionary();
      }
      return obj.ToJSON().ToDictionary();
    }

    /// <summary>
    /// 将对象转换成数据库对应类型的值
    /// </summary>
    /// <param name="val"></param>
    /// <returns></returns>
    public static object GetDBValue(this object val)
    {
      if (val == null)
      {
        return DBNull.Value;
      }
      if (val is JsonNumber)
      {
        return ((JsonNumber)val).ToSingle();
      }
      if (val is IDictionary || val is IList)
      {
        return val.ToJSON();
      }
      var type = Type.GetTypeCode(val.GetType());
      switch (type)
      {
        case TypeCode.Boolean:
          return (byte)((bool)val == true ? 1 : 0);
        case TypeCode.Double:
        case TypeCode.Decimal:
        case TypeCode.Int16:
        case TypeCode.UInt16:
        case TypeCode.Int32:
        case TypeCode.UInt32:
        case TypeCode.Int64:
        case TypeCode.UInt64:
        case TypeCode.Single:
        case TypeCode.Byte:
        case TypeCode.SByte:
          return val;
        case TypeCode.DateTime:
          return ((DateTime)val).ToDateTimeString();
        case TypeCode.Object:
          return val.ToJSON();
        default:
          return val.ToString();
      }
    }

    /// <summary>
    /// 获取指定对象的DBType
    /// </summary>
    /// <param name="val"></param>
    /// <returns></returns>
    public static DbType GetDBType(this object val)
    {
      if (val == null)
      {
        return DbType.AnsiString;
      }

      var type = Type.GetTypeCode(val.GetType());
      switch (type)
      {
        case TypeCode.Boolean:
          return DbType.Boolean;
        case TypeCode.Byte:
          return DbType.Byte;
        case TypeCode.DateTime:
          return DbType.DateTime;
        case TypeCode.Decimal:
          return DbType.Decimal;
        case TypeCode.Double:
          return DbType.Double;
        case TypeCode.Int16:
          return DbType.Int16;
        case TypeCode.Int32:
          return DbType.Int32;
        case TypeCode.Int64:
          return DbType.Int64;
        case TypeCode.Object:
          return DbType.Object;
        case TypeCode.SByte:
          return DbType.SByte;
        case TypeCode.Single:
          return DbType.Single;
        case TypeCode.UInt16:
          return DbType.UInt16;
        case TypeCode.UInt32:
          return DbType.UInt32;
        case TypeCode.UInt64:
          return DbType.UInt64;
        default:
          return DbType.String;
      }
    }

    /// <summary>
    /// 浅克隆当前对象到指定目标对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="srcObj"></param>
    /// <param name="targetObj"></param>
    /// <returns></returns>
    public static T Clone<T>(this T srcObj, T targetObj)
    {
      var type = typeof(ObjectClone<>).MakeGenericType(srcObj.GetType());
      return (T)type.InvokeStaticMethod("Clone", paramArr: new object[] { srcObj, targetObj });
    }

    /// <summary>
    /// 浅克隆当前对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="srcObj"></param>
    /// <returns></returns>
    public static T Clone<T>(this T srcObj)
    {
      var targetObj = srcObj.GetType().CreateInstance<T>();
      return srcObj.Clone(targetObj);
    }
    #endregion 基础对象扩展
  }
}
